﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Windows.Media;
using System.Xml;
using System.Xml.Serialization;

namespace Yxinmt.Utility
{
    public class Common
    {
        public static int PanelZIndex = 1000;

        public static int GetPanelZIndex()
        {
            PanelZIndex += 1;
            return PanelZIndex;
        }

        public static string RemoveEnterOrWhiteSpace(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                str = str.Replace("\n", "");
                while (str.IndexOf(" ") > 0)
                {
                    str = str.Replace(" ", "");
                }
            }
            return str;
        }

        public static byte[] CaptureScreen(int x, int y, int w, int h, int quality = 100, string format = "PNG")
        {
            MemoryStream ms = new MemoryStream();

            System.Drawing.Imaging.EncoderParameters ep = new System.Drawing.Imaging.EncoderParameters();
            ep.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, new long[] { quality });

            System.Drawing.Imaging.ImageCodecInfo imageCodecInfo = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders().Where(where => where.FormatDescription.Equals(format)).FirstOrDefault();

            using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(w, h))
            {
                bitmap.MakeTransparent();

                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap))
                {
                    g.CopyFromScreen(new System.Drawing.Point(x, y), System.Drawing.Point.Empty, bitmap.Size);
                }

                bitmap.Save(ms, imageCodecInfo, ep);
            }

            return ms.ToArray();
        }

        /// <summary>
        /// 弹出对话框
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static System.Windows.MessageBoxResult Alert(string entityName, string methodName, Exception ex)
        {
            ex = Utility.Common.GetInnerException(ex);
            Utility.LoggerProxy.Exception(entityName, methodName, ex);
            return System.Windows.MessageBox.Show(ex.Message, "提示信息");
        }

        public static System.Windows.MessageBoxResult Alert(string entityName, string methodName, string message, Exception ex)
        {
            ex = Utility.Common.GetInnerException(ex);
            Utility.LoggerProxy.Exception(entityName, methodName, ex);
            return System.Windows.MessageBox.Show(message, "提示信息");
        }

        public static System.Windows.MessageBoxResult Alert(string message)
        {
            return System.Windows.MessageBox.Show(message, "提示信息");
        }

        public static System.Windows.MessageBoxResult Confrim(string message)
        {
            return System.Windows.MessageBox.Show(message, "确认信息", System.Windows.MessageBoxButton.OKCancel);
        }

        public static System.Drawing.Color GetDrawingColor(string color)
        {
            return System.Drawing.ColorTranslator.FromHtml(color);
        }

        public static System.Windows.Media.Stretch GetStretch(string value)
        {
            switch (value)
            {
                case "Fill": return System.Windows.Media.Stretch.Fill;
                case "Uniform": return System.Windows.Media.Stretch.Uniform;
                case "UniformToFill": return System.Windows.Media.Stretch.UniformToFill;
                default: return System.Windows.Media.Stretch.None;
            }
        }

        public static System.Windows.Media.SolidColorBrush GetColorBrush(string value, int opacity = 0)
        {
            var color = new System.Windows.Media.SolidColorBrush(GetColor((string)value));
            if (opacity > 0) color.Opacity = opacity / 100;
            return color;
        }

        public static System.Windows.Media.Color GetColor(string color)
        {
            if (color.StartsWith("{")) throw new Exception(string.Format("未配置此{0}颜色！", color));
            try
            {
                return (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(color);
            }
            catch
            {
                throw new Exception(string.Format("颜色值{0}不正确！", color));
            }
        }
        public static MemoryStream StringToMemoryStream(string s)
        {
            MemoryStream memoryStream = new MemoryStream();
            byte[] buffer = Encoding.UTF8.GetBytes(s);
            memoryStream.Write(buffer, 0, buffer.Length);
            memoryStream.Position = 0;
            return memoryStream;
        }

        public static void SetProperty(Dictionary<string, object> dict, string name, Dictionary<string, object> property)
        {
            Dictionary<string, object> dict2 = GetProperty(dict, name);
            if (dict2 != null) foreach (var kvp in property) dict2[kvp.Key] = kvp.Value;
        }

        public static void SetProperty(Dictionary<string, object> dict, string key, string name, object value)
        {
            Dictionary<string, object> dict2 = GetProperty(dict, key);
            if (dict2 != null) dict2[name] = value;
        }

        public static void RemoveProperty(Dictionary<string, object> dict, string key, string name)
        {
            Dictionary<string, object> dict2 = GetProperty(dict, key);
            if (dict2 != null && dict2.ContainsKey(name)) dict2.Remove(name);
        }

        public static Dictionary<string, object> GetProperty(Dictionary<string, object> dict, string name)
        {
            if (dict != null && dict.ContainsKey("name") && dict["name"].ToString() == name) return dict;

            Dictionary<string, object> property = null;
            foreach (var kvp in dict)
            {
                if (kvp.Value is Dictionary<string, object>)
                {
                    property = GetProperty(kvp.Value as Dictionary<string, object>, name);
                    if (property != null) return property;
                }
                else if (kvp.Value is List<Dictionary<string, object>>)
                {
                    foreach (var d in kvp.Value as List<Dictionary<string, object>>)
                    {
                        property = GetProperty(d, name);
                        if (property != null) return property;
                    }
                }
            }

            return property;
        }

        public static System.Windows.VerticalAlignment GetVerticalAlignment(string value)
        {
            switch (value)
            {
                case "Bottom": return System.Windows.VerticalAlignment.Bottom;
                case "Center": return System.Windows.VerticalAlignment.Center;
                case "Stretch": return System.Windows.VerticalAlignment.Stretch;
                default: return System.Windows.VerticalAlignment.Top;
            }
        }

        public static System.Windows.HorizontalAlignment GetHorizontalAlignment(string value)
        {
            switch (value)
            {
                case "Center": return System.Windows.HorizontalAlignment.Center;
                case "Right": return System.Windows.HorizontalAlignment.Right;
                case "Stretch": return System.Windows.HorizontalAlignment.Stretch;
                default: return System.Windows.HorizontalAlignment.Left;
            }
        }


        public static System.Windows.Media.ImageSource GetImageSource(string url)
        {
#if DEBUG
            if (url.StartsWith("images/yxinmt_h5") || url.StartsWith("images/yxinmt_wpf")) url = "http://118.25.18.233:85/" + url;
#endif
            if (StateData.ImageDictionary.ContainsKey(url)) return StateData.ImageDictionary[url];

            System.Windows.Media.ImageSource imageSource = null;

            if (url.ToLower().StartsWith("http"))
            {
                string dir = AppDomain.CurrentDomain.BaseDirectory + "images\\";
                string localUrl = dir + url.Split('/').Last();
                if (!System.IO.Directory.Exists(dir)) Directory.CreateDirectory(dir);
                if (System.IO.File.Exists(localUrl))
                {
                    imageSource = (System.Windows.Media.ImageSource)new System.Windows.Media.ImageSourceConverter().ConvertFrom(File.ReadAllBytes(localUrl));
                }
                else
                {
                    System.Windows.Media.ImageSourceConverter imageSourceConverter = new System.Windows.Media.ImageSourceConverter();
                    System.IO.Stream stream = Utility.Common.GetImageStream(url);
                    if (stream == null) return null;
                    imageSource = (System.Windows.Media.ImageSource)new System.Windows.Media.ImageSourceConverter().ConvertFrom(stream);

                    if (stream is MemoryStream ms) SaveFile(ms, localUrl);
                }
            }
            else
            {
                string dir = AppDomain.CurrentDomain.BaseDirectory + "images\\";
                if (url.StartsWith("images/yxinmt_h5") || url.StartsWith("images/yxinmt_wpf")) url = dir + url.Split('/').Last();
                else url = AppDomain.CurrentDomain.BaseDirectory + url;

                try
                {
                    imageSource = (System.Windows.Media.ImageSource)new System.Windows.Media.ImageSourceConverter().ConvertFrom(File.ReadAllBytes(url));
                }
                catch
                {
                    throw new Exception("图片：" + url + "不存在");
                }
            }

            if (imageSource != null) StateData.ImageDictionary[url] = imageSource;

            return imageSource;
        }

        public static System.Drawing.Image GetDrawingImage(string url)
        {
#if DEBUG
            if (url.StartsWith("images/yxinmt_h5") || url.StartsWith("images/yxinmt_wpf")) url = "http://118.25.18.233:85/" + url;
#endif
            if (StateData.ImageDictionary2.ContainsKey(url)) return StateData.ImageDictionary2[url];

            System.Drawing.Image image = null;
            if (url.ToLower().StartsWith("http"))
            {
                string dir = AppDomain.CurrentDomain.BaseDirectory + "images\\";
                string localUrl = dir + url.Split('/').Last();
                if (!System.IO.Directory.Exists(dir)) Directory.CreateDirectory(dir);
                if (System.IO.File.Exists(localUrl))
                {
                    image = System.Drawing.Image.FromFile(localUrl);
                }
                else
                {
                    System.IO.Stream stream = Utility.Common.GetImageStream(url);
                    if (stream == null) return null;

                    image = System.Drawing.Image.FromStream(stream);
                    if (stream is MemoryStream ms) SaveFile(ms, localUrl);
                }
            }
            else
            {
                string dir = AppDomain.CurrentDomain.BaseDirectory + "images\\";
                if (url.StartsWith("images/yxinmt_h5") || url.StartsWith("images/yxinmt_wpf")) url = dir + url.Split('/').Last();

                try
                {
                    image = System.Drawing.Image.FromFile(url);
                }
                catch
                {
                    throw new Exception("图片：" + url + "不存在");
                }
            }

            if (image != null) StateData.ImageDictionary2[url] = image;

            return image;
        }

        public static void SaveConfig<T>(string name, T config)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + string.Format("configs\\{0}.json", name);

            string content = config == null ? string.Empty : JsonConvert.SerializeObject(config);

            using (TextWriter writer = new StreamWriter(path))
            {
                writer.Write(content);
                writer.Flush();
            }
        }

        public static T GetConfig<T>(string name)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + string.Format("configs\\{0}.json", name);

            string dirPath = AppDomain.CurrentDomain.BaseDirectory + "configs";
            if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);

            if (!File.Exists(path))
            {
                using (var f = File.Create(path))
                    return default(T);
            }

            string content = string.Empty;

            using (TextReader reader = new StreamReader(path))
            {
                content = reader.ReadToEnd();
            }

            if (string.IsNullOrEmpty(content)) return default(T);

            return JsonConvert.DeserializeObject<T>(content);
        }

        public static System.Windows.Media.ImageSource GetImageSource(System.IO.Stream stream)
        {
            System.Windows.Media.ImageSourceConverter imageSourceConverter = new System.Windows.Media.ImageSourceConverter();
            if (stream == null) return null;
            return (System.Windows.Media.ImageSource)new System.Windows.Media.ImageSourceConverter().ConvertFrom(stream);
        }

        public static System.Windows.Media.ImageSource GetImageSource(byte[] bs)
        {
            System.Windows.Media.ImageSourceConverter imageSourceConverter = new System.Windows.Media.ImageSourceConverter();
            if (bs == null) return null;
            return (System.Windows.Media.ImageSource)new System.Windows.Media.ImageSourceConverter().ConvertFrom(bs);
        }

        public static void SaveFile(MemoryStream ms, string fileName)
        {
            SaveFile(ms.ToArray(), fileName);
        }

        public static void SaveFile(byte[] bytes, string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
            {
                if (bytes != null) fs.Write(bytes, 0, bytes.Length);
                fs.Close();
            }
        }

        public static string GetTextContent(string fileName)
        {
            byte[] bs = File.ReadAllBytes(fileName);
            System.Text.Encoding encoding = System.Text.Encoding.Default;

            using (System.IO.BinaryReader br = new System.IO.BinaryReader(new MemoryStream(bs)))
            {
                byte[] buffer = br.ReadBytes(2);

                if (buffer[0] >= 0xEF)
                {
                    if (buffer[0] == 0xEF && buffer[1] == 0xBB) encoding = System.Text.Encoding.UTF8;
                    else if (buffer[0] == 0xFE && buffer[1] == 0xFF) encoding = System.Text.Encoding.BigEndianUnicode;
                    else if (buffer[0] == 0xFF && buffer[1] == 0xFE) encoding = System.Text.Encoding.Unicode;
                }
            }

            using (TextReader reader = new StreamReader(new MemoryStream(bs), encoding))
            {
                return reader.ReadToEnd();
            }
        }

        public static string GetFileSize(string fileName)
        {
            FileInfo fi = new FileInfo(fileName);
            return GetFileSize(fi.Length);
        }

        public static string GetFileSize(long length)
        {
            if (length < 1000) return string.Format("{0}B", length);

            decimal k = (decimal)length / (decimal)1024;
            if (k < 1000) return string.Format("{0}KB", decimal.Round(k, 2).ToString());

            k = k / 1024;
            if (k < 1000) return string.Format("{0}MB", decimal.Round(k, 2).ToString());

            k = k / 1024;
            return string.Format("{0}GB", decimal.Round(k, 2).ToString());
        }

        public static void CopyFile(string fileName, string saveFileName, string dir)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory;

            path = string.Format("{0}{1}", path, dir.Replace("/", "\\"));

            if (!Directory.Exists(path)) Directory.CreateDirectory(path);

            path += "\\" + saveFileName;

            FileInfo myfile = new FileInfo(fileName);
            myfile.CopyTo(path, true);
        }

        public static string GetPath(string dir)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory;

            return string.Format("{0}{1}", path, dir.Replace("/", "\\"));
        }

        /// <summary>
        /// 获取文件路径
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string GetFilePath(string dirPath, string fileName)
        {
            dirPath = InitDirPath(dirPath);
            return string.Format("{0}\\{1}", dirPath, fileName);
        }

        public static void DeleteFile(string fileName)
        {
            try
            {
                string path = AppDomain.CurrentDomain.BaseDirectory;

                path = string.Format("{0}{1}", path, fileName.Replace("/", "\\"));

                if (File.Exists(path)) File.Delete(path);
            }
            catch (Exception ex)
            {
                Utility.LoggerProxy.Exception("Common", "DeleteFile", ex);
            }
        }

        public static int GetWidthHeightRatio()
        {
            return System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenWidth);
        }

        /// <summary>
        /// 初始化目录路径
        /// </summary>
        public static string InitDirPath(string dirPath)
        {
            dirPath = GetPath(dirPath);
            if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
            return dirPath;
        }

        /// <summary>
        /// 匿名对象转换成键值对
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Dictionary<string, object> AnonymityToDictionary(object obj)
        {
            if (obj == null) return null;

            Dictionary<string, object> dict = new Dictionary<string, object>();

            object propertyValue = null;
            List<Dictionary<string, object>> dictList = null;

            obj.GetType().GetProperties().ToList().ForEach(p =>
            {
                propertyValue = p.GetValue(obj);

                if (propertyValue == null)
                {
                    dict.Add(p.Name, null);
                }
                else if (p.PropertyType == typeof(object))
                {
                    dict.Add(p.Name, AnonymityToDictionary(propertyValue));
                }
                else if (p.PropertyType == typeof(List<object>))
                {
                    dictList = new List<Dictionary<string, object>>();
                    (propertyValue as List<object>).ForEach(v =>
                    {
                        dictList.Add(AnonymityToDictionary(v));
                    });

                    dict.Add(p.Name, dictList);
                }
                else
                {
                    dict.Add(p.Name, propertyValue);
                }
            });

            return dict;
        }

        public static object ChangeType(object value, Type type)
        {
            if (value == null)
            {
                return null;
            }
            if (type != typeof(string) && string.IsNullOrEmpty(value.ToString()))
            {
                return null;
            }
            if (type == typeof(Guid) || type == typeof(Nullable<Guid>))
            {
                if (value is Guid)
                {
                    return value;
                }
                return new Guid(value.ToString());
            }
            else if (type == typeof(int) || type == typeof(Nullable<int>))
            {
                if (value is int)
                {
                    return value;
                }
                return int.Parse(value.ToString());
            }
            else if (type == typeof(char) || type == typeof(Nullable<char>))
            {
                if (value is char)
                {
                    return value;
                }
                return char.Parse(value.ToString());
            }
            else if (type == typeof(byte) || type == typeof(Nullable<byte>))
            {
                if (value is byte)
                {
                    return value;
                }
                return byte.Parse(value.ToString());
            }
            else if (type == typeof(short) || type == typeof(Nullable<short>))
            {
                if (value is short)
                {
                    return value;
                }
                return short.Parse(value.ToString());
            }
            else if (type == typeof(long) || type == typeof(Nullable<long>))
            {
                if (value is long)
                {
                    return value;
                }
                return long.Parse(value.ToString());
            }
            else if (type == typeof(decimal) || type == typeof(Nullable<decimal>))
            {
                if (value is decimal)
                {
                    return value;
                }
                return decimal.Parse(value.ToString());
            }
            else if (type == typeof(double) || type == typeof(Nullable<double>))
            {
                if (value is double)
                {
                    return value;
                }
                return double.Parse(value.ToString());
            }
            else if (type == typeof(bool) || type == typeof(Nullable<bool>))
            {
                if (value is bool)
                {
                    return value;
                }
                if (value.ToString() == "1")
                {
                    return true;
                }
                else if (value.ToString().Trim().ToLower() == "true")
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else if (type == typeof(float) || type == typeof(Nullable<float>))
            {
                if (value is float)
                {
                    return value;
                }
                return float.Parse(value.ToString());
            }
            else if (type == typeof(DateTime) || type == typeof(Nullable<DateTime>))
            {
                if (value is DateTime)
                {
                    return value;
                }
                return DateTime.Parse(value.ToString());
            }
            else if (type == typeof(string))
            {
                if (value is string)
                {
                    return value;
                }
                return value.ToString();
            }
            else if (type == typeof(byte[]) && value is string)
            {
                return value.ToString().Split(',').Select(s => byte.Parse(s)).ToArray();
            }
            else
            {
                return value;
            }
        }

        public static T GetValue<T>(object value)
        {
            object obj = ChangeType(value, typeof(T));

            if (obj == null) return default(T);

            return (T)obj;
        }

        /// <summary>
        /// 获取异常对象
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public static Exception GetInnerException(Exception ex)
        {
            if (ex.InnerException != null)
            {
                return GetInnerException(ex.InnerException);
            }
            return ex;
        }

        public static Dictionary<string, object> JsonToDictionary(string jsonText)
        {
            Dictionary<string, object> dict = JsonTo<Dictionary<string, object>>(jsonText);
            return ParseJsonContent(dict);
        }


        private static void ParseJsonContent(object obj, List<Dictionary<string, object>> dictList)
        {
            if (obj is Dictionary<string, object>)
            {
                dictList.Add(ParseJsonContent(obj));
            }
            else if (obj is object[] || obj is ArrayList)
            {
                var list = ParseJsonContentList(obj);
                if(list is List<Dictionary<string,object>> dictList2) dictList.AddRange(dictList2);
            }
        }

        static object JsonElementToObject(System.Text.Json.JsonElement ele)
        {
            if (ele.ValueKind == System.Text.Json.JsonValueKind.Object)
            {
                Dictionary<string, object> obj = new Dictionary<string, object>();
                foreach (var item in ele.EnumerateObject())
                {
                    obj[item.Name] = JsonElementToObject(item.Value);
                }
                return obj;
            }
            else if (ele.ValueKind == System.Text.Json.JsonValueKind.Array)
            {
                List<object> objList = new List<object>();
                foreach (var item in ele.EnumerateArray())
                {
                    objList.Add(JsonElementToObject(item));
                }
                return objList;
            }
            else if (ele.ValueKind == System.Text.Json.JsonValueKind.False) return false;
            else if (ele.ValueKind == System.Text.Json.JsonValueKind.True) return true;
            else if (ele.ValueKind == System.Text.Json.JsonValueKind.Number) return ele.GetDecimal();
            else if (ele.ValueKind == System.Text.Json.JsonValueKind.String) return ele.GetString();
            else if (ele.ValueKind == System.Text.Json.JsonValueKind.Null) return null;
            else if (ele.ValueKind == System.Text.Json.JsonValueKind.Undefined) return null;

            return ele.ToString();
        }

        public static Dictionary<string, object> ParseJsonContent(object obj)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>();
            if (obj is Dictionary<string, object>)
            {
                foreach (KeyValuePair<string, object> kvp in obj as Dictionary<string, object>)
                {
                    if (kvp.Value is Dictionary<string, object> || kvp.Value is JObject)
                    {
                        dict.Add(kvp.Key, ParseJsonContent(kvp.Value));
                    }
                    else if (kvp.Value is object[])
                    {
                        dict.Add(kvp.Key, ParseJsonContentList(kvp.Value));
                    }
                    else if (kvp.Value is ArrayList || kvp.Value is JArray)
                    {
                        dict.Add(kvp.Key, ParseJsonContentList(kvp.Value));
                    }
                    else if (kvp.Value is System.Text.Json.JsonElement ele)
                    {
                        dict.Add(kvp.Key, JsonElementToObject(ele));
                    }
                    else
                    {
                        dict.Add(kvp.Key, kvp.Value);
                    }
                }
            }
            else if (obj is JObject)
            {
                foreach (var kvp in (obj as JObject))
                {
                    if (kvp.Value is JObject) dict.Add(kvp.Key, ParseJsonContent(kvp.Value));
                    else if (kvp.Value is JArray) dict.Add(kvp.Key, ParseJsonContentList(kvp.Value));
                    else if (kvp.Value == null) dict.Add(kvp.Key, null);
                    else if (kvp.Value.Type is JTokenType.Boolean) dict.Add(kvp.Key, kvp.Value.ToObject<bool>());
                    else if (kvp.Value.Type is JTokenType.Bytes) dict.Add(kvp.Key, kvp.Value.ToObject<byte[]>());
                    else if (kvp.Value.Type is JTokenType.Date) dict.Add(kvp.Key, kvp.Value.ToObject<DateTime>());
                    else if (kvp.Value.Type is JTokenType.Float) dict.Add(kvp.Key, kvp.Value.ToObject<float>());
                    else if (kvp.Value.Type is JTokenType.Guid) dict.Add(kvp.Key, kvp.Value.ToObject<Guid>());
                    else if (kvp.Value.Type is JTokenType.Integer) dict.Add(kvp.Key, kvp.Value.ToObject<int>());
                    else if (kvp.Value.Type is JTokenType.String) dict.Add(kvp.Key, kvp.Value.ToObject<string>());
                    else dict.Add(kvp.Key, kvp.Value.ToString());
                }
            }
            return dict;
        }

        private static object ParseJsonContentList(object obj)
        {
            List<Dictionary<string, object>> dictList = new List<Dictionary<string, object>>();
            if (obj is object[])
            {
                object[] arrayObj = obj as object[];
                foreach (object item in arrayObj)
                {
                    if (item is Dictionary<string, object>)
                    {
                        dictList.Add(ParseJsonContent(item));
                    }
                }
            }
            else if (obj is ArrayList)
            {
                ArrayList arrayList = obj as ArrayList;
                foreach (object item in arrayList)
                {
                    if (item is Dictionary<string, object>)
                    {
                        dictList.Add(ParseJsonContent(item));
                    }
                }
            }
            else if (obj is JArray)
            {
                List<int> intList=null;
                List<string> stringList=null;
                foreach (var item in (obj as JArray))
                {
                    if (item is JObject)
                    {
                        dictList.Add(ParseJsonContent(item));
                    }
                    else if (item.Type == JTokenType.Integer)
                    {
                        if (intList == null) intList = new List<int>();
                        intList.Add((int)item);
                    }
                    else if (item.Type == JTokenType.String)
                    {
                        if (stringList == null) stringList = new List<string>();
                        stringList.Add((string)item);
                    }
                }
                if (intList != null) return intList;
                else if (stringList != null) return stringList;
            }
            return dictList;
        }

        /// <summary>
        /// 将键值对列表转化成指定对象列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dictList"></param>
        /// <returns></returns>
        public static List<T> DictionaryListToList<T>(List<Dictionary<string, object>> dictList) where T : class
        {
            List<T> objList = new List<T>();
            dictList.ForEach(dict =>
            {
                objList.Add(DictionaryTo<T>(dict));
            });
            return objList;
        }

        /// <summary>
        /// 将键值对转化成指定对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dict"></param>
        /// <returns></returns>
        public static T DictionaryTo<T>(Dictionary<string, object> dict) where T : class
        {
            T obj = Activator.CreateInstance<T>();
            return DictionaryToObject(dict, obj) as T;
        }

        /// <summary>
        /// 将键值对转化成指定对象
        /// </summary>
        /// <param name="dict"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static object DictionaryToObject(Dictionary<string, object> dict, object obj)
        {
            if (dict == null) return null;
            Type type = obj.GetType();
            foreach (KeyValuePair<string, object> kvp in dict)
            {
                PropertyInfo property = type.GetProperty(kvp.Key);
                if (property != null && kvp.Value != null && kvp.Value != DBNull.Value)
                {
                    Type propertyType = property.PropertyType;
                    object childObj = null;
                    if (kvp.Value is List<Dictionary<string, object>>)
                    {
                        if (propertyType.IsGenericType)
                        {
                            object childList = Activator.CreateInstance(propertyType);
                            Type argumentType = propertyType.GetGenericArguments()[0];
                            foreach (Dictionary<string, object> childDict in kvp.Value as List<Dictionary<string, object>>)
                            {
                                childObj = Activator.CreateInstance(argumentType);
                                childObj = DictionaryToObject(childDict, childObj);
                                propertyType.InvokeMember("Add", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, childList, new object[] { childObj });
                            }
                            property.SetValue(obj, childList, null);
                        }
                    }
                    else if (kvp.Value is Dictionary<string, object>)
                    {
                        childObj = Activator.CreateInstance(propertyType);
                        property.SetValue(obj, DictionaryToObject(kvp.Value as Dictionary<string, object>, childObj), null);
                    }
                    else
                    {
                        if (kvp.Value.GetType().Name == property.PropertyType.Name)
                        {
                            property.SetValue(obj, kvp.Value, null);
                        }
                        else
                        {
                            property.SetValue(obj, Common.ChangeType(kvp.Value, property.PropertyType), null);
                        }
                    }
                }
            }
            return obj;
        }

        public static string ToJson(object obj)
        {
            return JsonConvert.SerializeObject(obj);
        }

        public static T JsonTo<T>(string json)
        {
            return JsonConvert.DeserializeObject<T>(json);
        }

        public static object JsonToObject(string json, Type type)
        {
            return JsonConvert.DeserializeObject(json, type);
        }

        /// <summary>
        /// 计算流MD5值
        /// </summary>
        /// <returns></returns>
        public static string ComputeStreamMd5(Stream stream)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            byte[] bytes = md5.ComputeHash(stream);
            stream.Position = 0;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                sb.Append(bytes[i].ToString("x2"));
            }
            return sb.ToString();
        }

        public static string GetLocalIPAddress()
        {
            IPHostEntry ipe = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress[] ip = ipe.AddressList;
            for (int i = 0; i < ip.Length; i++)
            {
                if (ip[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) return ip[i].ToString();
            }
            return null;
        }

        private static string FormatMac(PhysicalAddress mac)
        {
            if (mac == null) return Utility.AppSetting.MacAddress;
            else
            {
                string str = mac.ToString();
                List<string> strList = new List<string>();
                int index = 0;
                while (index < str.Length)
                {
                    strList.Add(str.Substring(index, 2));
                    index += 2;
                }

                return string.Join("-", strList);
            }
        }

        public static string GetMacAddress()
        {
            return GetIpMacAddress(GetLocalIPAddress());
        }

        public static string GetIpMacAddress(string ip)
        {
            return FormatMac(GetIpPhysicalAddress(ip));
        }

        public static PhysicalAddress GetIpPhysicalAddress(string ip)
        {
            PhysicalAddress mac = null;

            List<NetworkInterface> list = (from a in NetworkInterface.GetAllNetworkInterfaces()
                                           where a.NetworkInterfaceType == NetworkInterfaceType.Ethernet
                                           && a.OperationalStatus == OperationalStatus.Up
                                           select a).ToList();

            if (list.Count == 0)
            {
                NetworkInterface net = (from a in NetworkInterface.GetAllNetworkInterfaces()
                                        where a.NetworkInterfaceType == NetworkInterfaceType.Ethernet
                                        select a).FirstOrDefault();
                return net == null ? null : net.GetPhysicalAddress();
            }
            else if (list.Count == 1) mac = list[0].GetPhysicalAddress();

            IPInterfaceProperties p = null;
            foreach (var n in list)
            {
                p = n.GetIPProperties();
                if (p.UnicastAddresses.ToList().Exists(w => w.Address.ToString() == ip)) return n.GetPhysicalAddress();
            }

            return list[0].GetPhysicalAddress();
        }

        public static string ComputeStringMd5(string str)
        {
            Stream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(str));
            return ComputeStreamMd5(stream);
        }

        public static T MapTo<T>(object obj) where T : class
        {
            T obj2 = Activator.CreateInstance<T>();
            return MapToObject(obj, obj2) as T;
        }

        private static object ObjectToObject(Type type, object obj1)
        {
            if (type == typeof(string) || type.IsValueType)
            {
                return Common.ChangeType(obj1, type);
            }
            else if (type.IsClass)
            {
                try
                {
                    object obj2 = Activator.CreateInstance(type);
                    return MapToObject(obj1, obj2);
                }
                catch
                {
                    return Common.ChangeType(obj1, type);
                }
            }
            else
            {
                return Common.ChangeType(obj1, type);
            }
        }

        public static List<Dictionary<string, object>> MapToDictionaryList<T>(List<T> list)
        {
            if (list == null) return null;
            return (from a in list select MapToDictionary<T>(a)).ToList();
        }

        public static Dictionary<string, object> MapToDictionary<T>(T obj)
        {
            return ObjectToDictionary(obj);
        }

        public static List<Dictionary<string, object>> ObjectToDictionaryList(List<object> list)
        {
            if (list == null) return null;
            return (from a in list select ObjectToDictionary(a)).ToList();
        }

        public static Dictionary<string, object> ObjectToDictionary(object obj)
        {
            if (obj == null) return null;

            Dictionary<string, object> dict = new Dictionary<string, object>();

            List<PropertyInfo> propertyList = obj.GetType().GetProperties().ToList();

            Type argumentType = null;
            object value = null;

            List<Dictionary<string, object>> childList = null;

            foreach (var c in propertyList)
            {
                value = c.GetValue(obj);

                if (c.PropertyType.IsGenericType && value is IEnumerable)
                {
                    argumentType = c.PropertyType.GetGenericArguments()[0];
                    childList = new List<Dictionary<string, object>>();

                    foreach (var childObj in GetObjectList(value as IEnumerable))
                    {
                        childList.Add(ObjectToDictionary(childObj));
                    }

                    dict.Add(c.Name, childList);
                }
                else
                {
                    dict.Add(c.Name, value);
                }
            }

            return dict;
        }

        public static object MapToObject(object source, object target)
        {
            if (source == null) return null;

            var list = (from a in source.GetType().GetProperties()
                        from b in target.GetType().GetProperties()
                        where a.Name.Equals(b.Name)
                        select new { a, b });

            Type argumentType = null;
            object value = null;
            object childObj = null;
            object childList = null;
            Type elementType = null;
            ArrayList objList = null;

            foreach (var c in list)
            {
                value = c.a.GetValue(source);

                if (c.a.PropertyType == c.b.PropertyType)
                {
                    c.b.SetValue(target, value);
                }
                else
                {
                    if (c.b.PropertyType.IsGenericType && value is IEnumerable)
                    {
                        argumentType = c.b.PropertyType.GetGenericArguments()[0];
                        childList = Activator.CreateInstance(c.b.PropertyType);

                        foreach (var obj in GetObjectList(value as IEnumerable))
                        {
                            childObj = ObjectToObject(argumentType, obj);

                            c.b.PropertyType.InvokeMember("Add", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, childList, new object[] { childObj });
                        }

                        c.b.SetValue(target, childList);
                    }
                    else if (c.b.PropertyType.IsArray)
                    {
                        elementType = c.b.PropertyType.GetElementType();
                        objList = new ArrayList();

                        if (value is IEnumerable)
                        {
                            foreach (var item in value as IEnumerable)
                            {
                                childObj = ObjectToObject(elementType, item);
                                objList.Add(childObj);
                            }
                        }
                        else
                        {
                            objList = value as ArrayList;
                        }

                        if (objList != null)
                        {
                            c.b.SetValue(target, objList.ToArray(elementType));
                        }
                    }
                    else
                    {
                        c.b.SetValue(target, ObjectToObject(c.b.PropertyType, value));
                    }
                }
            }

            return target;
        }

        private static IEnumerable<object> GetObjectList(IEnumerable obj)
        {
            IEnumerator point = obj.GetEnumerator();
            while (point.MoveNext())
            {
                yield return point.Current;
            }
        }

        public static MemoryStream GetFileStream(string path)
        {
            FileWebRequest webRequest = (FileWebRequest)HttpWebRequest.Create(path);
            webRequest.Timeout = 60 * 1000 * 20;
            using (FileWebResponse webResponse = (FileWebResponse)webRequest.GetResponse())
            {
                Stream stream = webResponse.GetResponseStream();

                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, bytes.Length);

                return new MemoryStream(bytes);
            }
        }

        public static byte[] GetHttpFileBytes(string url)
        {
            HttpClient client = new HttpClient();
            client.Timeout = new TimeSpan(0, 20, 0);
            return client.GetByteArrayAsync(url).Result;
        }

        public static MemoryStream GetHttpFileStream(string url)
        {
            HttpClient client = new HttpClient();
            client.Timeout = new TimeSpan(0, 20, 0);
            using (Stream stream = client.GetStreamAsync(url).Result)
            {
                MemoryStream memoryStream = new MemoryStream();

                int count = 0;
                byte[] buffer = new byte[1024];
                while ((count = stream.Read(buffer, 0, 1024)) > 0)
                {
                    memoryStream.Write(buffer, 0, count);
                }
                memoryStream.Position = 0;

                return memoryStream;
            }
        }

        public static System.Drawing.Image GetImage(string url)
        {
            return System.Drawing.Image.FromStream(GetImageStream(url));
        }

        public static Stream GetImageStream(string url)
        {
            System.IO.MemoryStream ms = new MemoryStream();
            var webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.ProtocolVersion = HttpVersion.Version11;
            using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
            {
                Stream stream = webResponse.GetResponseStream();
                if (webResponse.StatusCode == HttpStatusCode.OK)
                {
                    stream.CopyTo(ms);
                    ms.Position = 0;
                    return ms;
                }
            }

            return null;
        }

        private static void GetFileList(Dictionary<string, object> dict, string rootPath, string path)
        {
            foreach (string f in Directory.GetFiles(path))
            {
                dict.Add(f.Substring(rootPath.Length), File.ReadAllBytes(f));
            }

            foreach (string f in Directory.GetDirectories(path))
            {
                GetFileList(dict, rootPath, f);
            }
        }

        public static void Compress(string dirPath, string fileName)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>();
            GetFileList(dict, dirPath, dirPath);

            IFormatter formatter = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                formatter.Serialize(ms, dict);
                ms.Position = 0;
                CreateCompressFile(ms, fileName);
            }
        }

        public static void SaveImage(string url, string fileName)
        {
            System.Drawing.Image img = GetImage(url);
            img.Save(fileName);
        }

        private static void CreateCompressFile(Stream source, string fileName)
        {
            using (Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
            {
                using (GZipStream output = new GZipStream(stream, CompressionMode.Compress))
                {
                    byte[] bytes = new byte[4096];
                    int n = 0;
                    while ((n = source.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        output.Write(bytes, 0, n);
                    }
                }
            }
        }

        public static byte[] CompressBytes(byte[] bs)
        {
            MemoryStream source = new MemoryStream(bs);
            MemoryStream ms = new MemoryStream();
            using (GZipStream output = new GZipStream(ms, CompressionMode.Compress))
            {
                byte[] bytes = new byte[4096];
                int n = 0;
                while ((n = source.Read(bytes, 0, bytes.Length)) != 0)
                {
                    output.Write(bytes, 0, n);
                }
            }
            return ms.ToArray();
        }

        public static byte[] DeCompressBytes(byte[] bs)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                using (GZipStream input = new GZipStream(new MemoryStream(bs), CompressionMode.Decompress, true))
                {
                    byte[] bytes = new byte[4096];
                    int n = 0;
                    while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        ms.Write(bytes, 0, n);
                    }
                }
                ms.Flush();
                ms.Position = 0;
                return ms.ToArray();
            }
        }

        public static void DeCompress(Stream source, string dirPath)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                using (GZipStream input = new GZipStream(source, CompressionMode.Decompress, true))
                {
                    byte[] bytes = new byte[4096];
                    int n = 0;
                    while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        ms.Write(bytes, 0, n);
                    }
                }
                ms.Flush();
                ms.Position = 0;
                DeSerializeFiles(ms, dirPath);
            }
        }

        public static void DeCompress(byte[] source, string dirPath)
        {
            DeCompress(new MemoryStream(source), dirPath);
        }

        public static void DeCompress(string fileName, string dirPath)
        {
            using (Stream source = File.OpenRead(fileName))
            {
                DeCompress(source, dirPath);
            }
        }

        private static void DeSerializeFiles(Stream stream, string dirPath)
        {
            BinaryFormatter bf = new BinaryFormatter();
            Dictionary<string, object> dict = (Dictionary<string, object>)bf.Deserialize(stream);

            string fileName = string.Empty;
            string dir = string.Empty;

            foreach (var kvp in dict)
            {
                fileName = string.Concat(dirPath, kvp.Key);
                dir = Path.GetDirectoryName(fileName);

                if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);

                byte[] bytes = (byte[])kvp.Value;
                using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                {
                    fs.Write(bytes, 0, bytes.Length);
                    fs.Close();
                }
            }
        }

        /// <summary>
        /// 对象序例化成XML
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string XmlSerialize<T>(T obj)
        {
            XmlSerializerNamespaces nameSpace = new XmlSerializerNamespaces();
            nameSpace.Add("", "");
            MemoryStream ms = new MemoryStream();
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
            using (XmlWriter xmlWriter = XmlWriter.Create(ms))
            {
                xmlSerializer.Serialize(xmlWriter, obj, nameSpace);
            }
            return Encoding.UTF8.GetString(ms.ToArray());
        }

        /// <summary>  
        /// XML反序列化成对象  
        /// </summary>  
        public static T XmlDeserialize<T>(string xml)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
            using (TextReader textReader = new StringReader(xml))
            {
                return (T)xmlSerializer.Deserialize(textReader);
            }
        }

        /// <summary>
        /// 字符串转化成Base64编码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ToBase64String(string str)
        {
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(str));
        }

        /// <summary>
        /// Base64编码转化成字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string FromBase64String(string str)
        {
            return Encoding.UTF8.GetString(Convert.FromBase64String(str));
        }

        /// <summary>
        /// SHA1withRSA签名
        /// </summary>
        /// <param name="content"></param>
        /// <param name="xmlString"></param>
        /// <returns></returns>
        public static string SHA1Sign(string content, string xmlString)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(content);
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(xmlString);
            using (var sh = SHA1.Create())
            {
                return BytesToHexString(rsa.SignData(bytes, sh));
            }
        }

        /// <summary>
        /// 取得证书私钥
        /// </summary>
        /// <param name="pfxPath">证书的绝对路径</param>
        /// <param name="password">访问证书的密码</param>
        /// <returns></returns>
        public static String GetPrivateKey(string pfxPath, string password)
        {
            X509Certificate2 pfx = new X509Certificate2(pfxPath, password, X509KeyStorageFlags.Exportable);
            return pfx.PrivateKey.ToXmlString(true);
        }

        /// <summary>
        /// 取得证书的公钥
        /// </summary>
        /// <param name="cerPath">证书的绝对路径</param>
        /// <returns></returns>
        public static String GetPublicKey(string cerPath)
        {
            X509Certificate2 cer = new X509Certificate2(cerPath);
            return cer.PublicKey.Key.ToXmlString(false);
        }

        /// <summary>
        /// 验签
        /// </summary>
        /// <param name="content"></param>
        /// <param name="sign"></param>
        /// <param name="xmlString"></param>
        /// <returns></returns>
        public static bool SHA1VerifySign(string content, string sign, string xmlString)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(xmlString);
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
            return rsa.VerifyData(Convert.FromBase64String(content), sha1, HexStringToBytes(sign));
        }

        /// <summary>
        /// 字节数组转化成十六进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string BytesToHexString(byte[] bytes)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                sb.Append(bytes[i].ToString("X2"));
            }
            return sb.ToString(); ;
        }

        /// <summary>
        /// 十六进制字符串转换成字节数组
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] HexStringToBytes(string str)
        {
            str = str.Replace("\n", "");
            str = str.Replace("\r", "");
            str = str.Trim();
            byte[] bytes = new byte[str.Length / 2];
            for (int i = 0; i < str.Length; i += 2) bytes[i / 2] = Convert.ToByte(str.Substring(i, 2), 16);
            return bytes;
        }

        public static T GetConcurrentQueuetItem<T>(System.Collections.Concurrent.ConcurrentQueue<T> list, Func<T, bool> where, bool blDesc = false)
        {
            List<T> list2 = new List<T>();
            T data = default(T);

            T lastData = default(T);

            if (blDesc)
            {
                lastData = list.Reverse().Where(f => where(f)).FirstOrDefault();
                if (lastData == null) return data;
                else
                {
                    while (!list.IsEmpty && list.Count > 0)
                    {
                        if (list.TryDequeue(out data))
                        {
                            if (data.Equals(lastData)) break;
                            else list2.Add(data);
                        }
                        else break;
                    }
                }
            }
            else
            {
                while (!list.IsEmpty && list.Count > 0)
                {
                    if (list.TryDequeue(out data))
                    {
                        if (where(data)) break;
                        else list2.Add(data);
                    }
                    else break;
                }
            }

            if (list.Count > 0) list2.ForEach(d => list.Enqueue(d));

            return data;
        }

        public static List<List<T>> ListToBatchList<T>(List<T> list, int num)
        {
            List<List<T>> batchList = new List<List<T>>();
            List<T> list2 = null;

            int count = list.Count % num == 0 ? list.Count / num : list.Count / num + 1;

            for (int i = 1; i <= count; i++)
            {
                list2 = new List<T>();

                for (int j = (i - 1) * num; j < i * num; j++) if (j < list.Count) list2.Add(list[j]);

                batchList.Add(list2);
            }

            return batchList;
        }

        public static List<T[]> ArrayToBatchList<T>(T[] arrs, int num, Func<int, int, int, T[]> initArray = null, int initStartIndex = 0)
        {
            List<T[]> batchList = new List<T[]>();
            T[] arrs2 = null;

            int count = arrs.Length % num == 0 ? arrs.Length / num : arrs.Length / num + 1;
            int len = 0;
            int startIndex = 0;

            for (int i = 1; i <= count; i++)
            {
                startIndex = (i - 1) * num;
                len = i == count ? arrs.Length - startIndex : num;
                arrs2 = initArray == null ? new T[len] : initArray(i, count, len);

                for (int j = startIndex; j < i * num; j++) if (j < arrs.Length) arrs2[j - startIndex + initStartIndex] = arrs[j];

                batchList.Add(arrs2);
            }

            return batchList;
        }

        public static void ConcurrentStackRemove<T>(ConcurrentStack<T> list, T obj)
        {
            T item = default(T);

            List<T> list2 = new List<T>();

            while (!list.IsEmpty && list.Count > 0)
            {
                if (list.TryPop(out item))
                {
                    if (obj.Equals(item)) break;
                    else list2.Add(item);
                }
                else break;
            }

            if (list2.Count > 0)
            {
                list2.Reverse();
                list2.ForEach(d => list.Push(d));
            }
        }

        public static string AddUrlRandom(string url)
        {
            if (string.IsNullOrEmpty(url)) return string.Empty;

            string rc = Common.GetRandomChars();
            string rd = DateTime.Now.ToString("yyyyMMddHHmmssfff") + new Random().Next(100000, 999999);
            url += url.IndexOf("?") > 0 ? "&" : "?";
            url += string.Format("_r{0}={1}", rc, rd);

            return url;
        }

        public static string GetRandomChars(int len = 0)
        {
            len = len == 0 ? 10 : len;
            char[] chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz".ToCharArray();
            List<char> list = new List<char>();
            Random r = new Random((int)DateTime.Now.Ticks);
            for (int i = 0; i < len; i++)
            {
                list.Add(chars[r.Next(0, chars.Length - 1)]);
            }
            return string.Join("", list);
        }

        public static double GetStringWidth(string str, double fontSize)
        {
            if (string.IsNullOrEmpty(str)) return 0;

            double count = 0;
            foreach (char ch in str)
            {
                count += ((int)ch) > 255 ? 2 : 1;
            }

            return fontSize * count / 2 + 10;
        }

        public static double GetStringHeight(string str, double width, double fontSize)
        {
            double strWidth = GetStringWidth(str, fontSize);

            return (Convert.ToInt32(strWidth / width) + 1) * (fontSize + fontSize / 2 + 1);
        }

        public static string DateToString(DateTime? date)
        {
            if (date == null)
            {
                return string.Empty;
            }
            return date.Value.ToString("yyyy-MM-dd HH:mm:ss");
        }


        public static T GetJsonData<T>(string dirPath, string name)
        {
            if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);

            string path = string.Format("{0}\\{1}.json", dirPath, name);

            if (!File.Exists(path))
            {
                using (var f = File.Create(path)) return default(T);
            }

            string content = string.Empty;

            using (TextReader reader = new StreamReader(path))
            {
                content = reader.ReadToEnd();
            }

            if (string.IsNullOrEmpty(content)) return default(T);

            return JsonConvert.DeserializeObject<T>(content);
        }

        public static void SaveJsonData<T>(string dirPath, string name, T obj)
        {
            if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);

            string path = string.Format("{0}\\{1}.json", dirPath, name);

            string content = JsonConvert.SerializeObject(obj);

            using (TextWriter writer = new StreamWriter(path))
            {
                writer.Write(content);
                writer.Flush();
            }
        }

        public static string GetRandomColor()
        {
            Random RandomNum_First = new Random((int)DateTime.Now.Ticks);

            System.Threading.Thread.Sleep(RandomNum_First.Next(50));

            Random RandomNum_Sencond = new Random((int)DateTime.Now.Ticks);

            int int_Red = RandomNum_First.Next(256);
            int int_Green = RandomNum_Sencond.Next(256);
            int int_Blue = (int_Red + int_Green > 400) ? 0 : 400 - int_Red - int_Green;

            int_Blue = (int_Blue > 255) ? 255 : int_Blue;

            return System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(int_Red, int_Green, int_Blue));
        }

        public static bool CompareBytes(byte[] a, byte[] b)
        {
            if (a == null && b == null) return true;
            if (a == null || b == null) return false;

            if (a.Length != b.Length) return false;

            bool blEquals = true;
            for (int i = 0; i < a.Length; i++)
            {
                if (a[i] != b[i]) { blEquals = false; break; }
            }
            return blEquals;
        }

        public static long GetDateTotalMilliseconds(DateTime dateTime)
        {
            return (long)(dateTime.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalMilliseconds;
        }

        public static int GetStringHeaderWidth(string strValue)
        {
            char[] chValue = strValue.ToCharArray();
            int iWidth = 0;
            bool isTrue;
            foreach (char ch in chValue)
            {
                isTrue = false;
                if (!isTrue)
                {
                    if (char.IsNumber(ch))
                    {
                        iWidth += 7;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsLower(ch))
                    {
                        iWidth += 7;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsUpper(ch))
                    {
                        iWidth += 8;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsPunctuation(ch))
                    {
                        iWidth += 11;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsSeparator(ch))
                    {
                        iWidth += 11;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsSymbol(ch))
                    {
                        iWidth += 11;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    iWidth += 15;
                }

            }
            return iWidth;
        }

        /// <summary>
        /// 该方法获取字符串长度
        /// </summary>
        /// <param name="strValue"></param>
        /// <returns></returns>
        public static int GetStringWidth(string strValue)
        {
            char[] chValue = strValue.ToCharArray();
            int iWidth = 0;
            bool isTrue;
            foreach (char ch in chValue)
            {
                isTrue = false;
                if (!isTrue)
                {
                    if (char.IsNumber(ch))
                    {
                        iWidth += 7;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsLower(ch))
                    {
                        iWidth += 7;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsUpper(ch))
                    {
                        iWidth += 8;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsPunctuation(ch))
                    {
                        iWidth += 11;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsSeparator(ch))
                    {
                        iWidth += 11;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    if (char.IsSymbol(ch))
                    {
                        iWidth += 11;
                        isTrue = true;
                    }
                }
                if (!isTrue)
                {
                    iWidth += 13;
                }

            }
            return iWidth;
        }
    }
}
